package sim1011.behaviours;

import javax.sound.sampled.ReverbType;

import jade.core.Agent;
import jade.core.behaviours.TickerBehaviour;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import sim1011.poltergeist.Poltergeist;
import sim1011.starter.EctoMobileStarter;
import sim1011.starter.Logger;

public class ESPPhotographerBehaviour extends TickerBehaviour {
	private static final long serialVersionUID = 4984311764512160288L;

	public ESPPhotographerBehaviour(Agent a, long period) {
		super(a, period);
	}

	@Override
	protected void onTick() {
		try {
			// inizializzazione del DFAgentDescription da cercare
			DFAgentDescription DFADtoSearch = new DFAgentDescription();
			ServiceDescription sd = new ServiceDescription();
			sd.setType("ecto-resource");
			DFADtoSearch.addServices(sd);
			// inizializzo il contatore di rispose
			int resourceManagerResponseCounter = 0;
			// preparo il messaggio
			ACLMessage requestStatusMessage = new ACLMessage(ACLMessage.REQUEST);
			int counter = ((Poltergeist) myAgent).getStatus()
					.getStatusRequestCounter();
			requestStatusMessage.setContent(Integer.toString(counter));
			// scoperta dei resource magager
			DFAgentDescription[] result = DFService.search(myAgent,
					DFADtoSearch);
			for (int i = 0; i < result.length; ++i)
				// imposto i destinatari del messaggio
				requestStatusMessage.addReceiver(result[i].getName());
			// invio il messaggio
			myAgent.send(requestStatusMessage);
			// mi metto in attesa delle risposte
			int resNumber = ((Poltergeist) myAgent).getStatus()
					.getResourceManagersNumber();
			((Poltergeist) myAgent).getStatus().incrementStatusRequestCounter();
			while (resNumber != resourceManagerResponseCounter) {
				// resto in attesa finche non arriva un messaggio di tipo
				// confirm
				MessageTemplate messageToReceiveTemplate = MessageTemplate
						.MatchPerformative(ACLMessage.CONFIRM);
				ACLMessage receivedMessage = myAgent
						.receive(messageToReceiveTemplate);
				if (receivedMessage != null) {
					// prendo il nome del RM che ha risposto
					String resourceManagerName = receivedMessage.getSender()
							.getLocalName();
					// Parsing del contenuto del messaggio
					String[] messageContent = receivedMessage.getContent()
							.split("#");
					// confronto il numero di richiesta con quello ricevuto
					int receivedStatusRequestNumber = new Integer(
							messageContent[0]).intValue();
					resourceManagerResponseCounter++;
					if (receivedStatusRequestNumber != counter) {
						System.err.println("NUMERO DI SEQUENZA ERRATO");
					} else {
						// aggiungo la cpu libera ottenuta alla sommatoria
						Integer newFreeCpu = new Integer(messageContent[1]);
						((Poltergeist) myAgent).getStatus().addFreeCpu(
								resourceManagerName, newFreeCpu.intValue());
						// aggiungo la memoria libera ottenuta alla sommatoria
						Integer newFreeMemory = new Integer(messageContent[2]);
						((Poltergeist) myAgent).getStatus().addFreeMemory(
								resourceManagerName, newFreeMemory.intValue());
						Logger.log("[ESP] received from: "
								+ resourceManagerName + " CPU: "
								+ newFreeCpu.intValue() + " MEMORY: "
								+ newFreeMemory);
						Float batteryReceived = new Float(messageContent[3]);
						if (receivedMessage.getSender().getLocalName().equals(EctoMobileStarter.MOBILE_NODE_NAME)) {
							if (batteryReceived.floatValue() > 0.0f) {
								Float newBatteryLevel = new Float(messageContent[3]);
								((Poltergeist) myAgent).getStatus()
										.setBatteryLevel(
												newBatteryLevel.floatValue());
							} else {
								float newBatteryLevel = 0.0f;
								((Poltergeist) myAgent).getStatus()
										.setBatteryLevel(
												newBatteryLevel);
							}
						}
						Float currentCost = new Float(messageContent[4]);
						((Poltergeist) myAgent).getStatus().addCost(
								currentCost.floatValue());
						// aggiungo il throughput del nodo da cui ho ricevuto il messaggio
						((Poltergeist) myAgent).getStatus().addThroughtput(
								new Float(messageContent[5]).floatValue());
					}
				} else {
					block();
				}
			}
			((Poltergeist) myAgent).getStatus().writeStats();
			((Poltergeist) myAgent).getStatus().resetThroughput();
			((Poltergeist) myAgent).getStatus().fixTrafficOnTick();
			/*if (((Poltergeist) myAgent).getStatus().getStatusRequestCounter() == EctoMobileStarter.HOW_MANY_MEASURES_ON_RUN) {
				((Poltergeist)myAgent).getStatus().finalizeStatistics();
				//EctoMobileStarter.mainThread.notify();
				System.exit(0);
			}*/
			if(((Poltergeist)myAgent).getStatus().getBatteryLevel() < 1.0f && ((Poltergeist) myAgent).getStatus().getStatusRequestCounter() > EctoMobileStarter.HOW_MANY_MEASURES_ON_RUN) {
				((Poltergeist)myAgent).getStatus().finalizeStatistics();
				System.exit(0);
			}
		} catch (FIPAException fe) {
			fe.printStackTrace();
		}
	}
}